package com.jstyle.jclife.utils;

import android.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.util.Log;

import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.data.DataPoint;
import com.google.android.gms.fitness.data.DataSet;
import com.google.android.gms.fitness.data.DataSource;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.data.Field;
import com.google.android.gms.tasks.OnCanceledListener;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.Task;
import com.jstyle.jclife.BuildConfig;
import com.jstyle.jclife.NetWork.NetWorkUtil;
import com.jstyle.jclife.R;
import com.jstyle.jclife.daoManager.HeartDataDaoManager;
import com.jstyle.jclife.daoManager.StepDetailDataDaoManager;
import com.jstyle.jclife.model.HeartData;
import com.jstyle.jclife.model.NetResultData;
import com.jstyle.jclife.model.StepDetailData;
import com.jstyle.jclife.model.UploadData;
import com.jstyle.jclife.model.UploadGpsData;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.logging.SimpleFormatter;

import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class UploadUtils {
    private static final String TAG = "UploadUtils";

    public static void uploadData(UploadData uploadData) {
        NetWorkUtil.getInstance().getJstyleApi()
                .uploadData(uploadData).compose(SchedulersTransformer.<NetResultData>io2MainObservable()).subscribe(new Observer<NetResultData>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(NetResultData netResultData) {

            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: " + e.getLocalizedMessage());
            }

            @Override
            public void onComplete() {

            }
        });
    }
    public static void uploadOtaLogData(Context context,String deviceType,String fwVersion,String content) {
        Map<String, String> logMap = new HashMap<>();
        String uid=NetWorkUtil.getUserId();
        String appName=context.getString(R.string.app_name);
        String appVersion= BuildConfig.VERSION_NAME;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date=format.format(new Date());
        logMap.put(NetWorkConast.KEY_uid,uid);
        logMap.put(NetWorkConast.KEY_exType,"Ota");
        logMap.put(NetWorkConast.KEY_AppName,appName);
        logMap.put(NetWorkConast.KEY_AppVersion,appVersion);
        logMap.put(NetWorkConast.KEY_devicetype,deviceType);
        logMap.put(NetWorkConast.KEY_osType,"Android "+ Build.VERSION.SDK_INT);
        logMap.put(NetWorkConast.KEY_LOGContent,content);
        logMap.put(NetWorkConast.KEY_FimwareVersion,fwVersion);
        logMap.put(NetWorkConast.KEY_LOGDate,date);
        NetWorkUtil.getInstance().getJstyleApi()
                .uploadOtaLog(logMap).compose(SchedulersTransformer.<NetResultData>io2MainObservable()).subscribe(new Observer<NetResultData>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(NetResultData netResultData) {
                Log.i(TAG, "onNext: ");
            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: " + e.getLocalizedMessage());
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public static void uploadGpsData(UploadGpsData uploadData) {
        NetWorkUtil.getInstance().getJstyleApi()
                .uploadGpsData(uploadData).compose(SchedulersTransformer.<NetResultData>io2MainObservable()).subscribe(new Observer<NetResultData>() {
            @Override
            public void onSubscribe(Disposable d) {

            }

            @Override
            public void onNext(NetResultData netResultData) {

            }

            @Override
            public void onError(Throwable e) {
                Log.i(TAG, "onError: " + e.getCause());
            }

            @Override
            public void onComplete() {

            }
        });
    }

    public static UploadData getUploadData(String deviceAddress, String dataType) {
        UploadData uploadData = new UploadData();
        uploadData.setMac(deviceAddress);
        uploadData.setDataType(dataType);
        uploadData.setUid(NetWorkUtil.getUserId());
        return uploadData;
    }

    public static UploadGpsData getUploadGpsData(String deviceAddress) {
        UploadGpsData uploadData = new UploadGpsData();
        uploadData.setMac(deviceAddress);
        uploadData.setDataType(NetWorkConast.gps);
        uploadData.setUid(NetWorkUtil.getUserId());
        return uploadData;
    }

    public static void createDataForRequest(Context context) {
        GoogleSignInAccount googleSignInAccount= GoogleSignIn.getLastSignedInAccount(context);
        if(googleSignInAccount==null)return;
        DataSource dataSourceStep =
                new DataSource.Builder()
                        .setAppPackageName(context)
                        .setDataType(DataType.TYPE_STEP_COUNT_DELTA)
                        .setStreamName("streamName")
                        .setType(DataSource.TYPE_RAW)
                        .build();
        DataSet dataSetStep = DataSet.create(dataSourceStep);
        DataSource dataSourceDistance =
                new DataSource.Builder()
                        .setAppPackageName(context)
                        .setDataType(DataType.TYPE_DISTANCE_DELTA)
                        .setStreamName("streamName")
                        .setType(DataSource.TYPE_RAW)
                        .build();
        DataSet dataSetDistance = DataSet.create(dataSourceDistance);

        DataSource dataSourceCal =
                new DataSource.Builder()
                        .setAppPackageName(context)
                        .setDataType(DataType.TYPE_CALORIES_EXPENDED)
                        .setStreamName("streamName")
                        .setType(DataSource.TYPE_RAW)
                        .build();
        DataSet dataSetCal = DataSet.create(dataSourceCal);
//        List<StepData>stepDataList= StepDataDaoManager.queryAllData();
        List<StepDetailData> stepDetailDataList = StepDetailDataDaoManager.queryAllDataAddress();
        for (StepDetailData stepDetailData : stepDetailDataList) {
            int step = Integer.valueOf(stepDetailData.getStep());
            float distance = Float.valueOf(stepDetailData.getDistance());
            float cal = Float.valueOf(stepDetailData.getCal());
            String time = stepDetailData.getDate();
            // Log.i(TAG, "createStepDataForRequest: "+time+" "+step+" "+distance);
            long startTime = DateUtil.getDefaultLongMi(time);
            Log.i(TAG, "createDataForRequest: "+time);

            if (startTime > System.currentTimeMillis()){
                startTime=System.currentTimeMillis();
            }
            long endTime = startTime + 9 * 60 * 1000l;
            DataPoint dataPoint =
                    dataSetStep.createDataPoint().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
            dataPoint.setIntValues(step > 5400 ? 5400 : step);   //最大值1分钟600步？
            dataSetStep.add(dataPoint);
            DataPoint dataPointDis =
                    dataSetDistance.createDataPoint().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
           dataPointDis.setFloatValues(distance>5000?5:distance / 1000);
            Log.i(TAG, "createDataForRequest: "+distance);
           // Log.i(TAG, "createDataForRequest: "+cal);
            dataSetDistance.add(dataPointDis);

            DataPoint dataPointCal =
                    dataSetCal.createDataPoint().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
            dataPointCal.setFloatValues(cal>300?300:cal);
          //  dataPointCal.setFloatValues(300);
            dataSetCal.add(dataPointCal);
        }
        insetData(dataSetStep, context);
        insetData(dataSetDistance, context);
        insetData(dataSetCal, context);
    }

    private static void insetData(final DataSet dataSet, Context context) {
        GoogleSignInAccount googleSignInAccount= GoogleSignIn.getLastSignedInAccount(context);
        if(googleSignInAccount==null||dataSet.isEmpty())return;

        Fitness.getHistoryClient(context, googleSignInAccount).insertData(dataSet).addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                Log.i(TAG, "onComplete: "+dataSet.getDataType());
                if(!task.isSuccessful()){
                    Log.i(TAG, "onComplete fail: "+dataSet.getDataType()+" "+task.getException());
                }
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.i(TAG, "onFailure: "+dataSet.getDataType()+" "+e.getMessage());
            }
        }).addOnCanceledListener(new OnCanceledListener() {
            @Override
            public void onCanceled() {
                Log.i(TAG, "onCanceled: ");
            }
        });
    }

    public static void createHeartDataForRequest(Context context) {
        DataSource dataSourceHr =
                new DataSource.Builder()
                        .setAppPackageName(context)
                        .setDataType(DataType.TYPE_HEART_RATE_BPM)
                        .setStreamName("streamName")
                        .setType(DataSource.TYPE_RAW)
                        .build();
        DataSet dataSetHr = DataSet.create(dataSourceHr);
        List<HeartData> heartDataList = HeartDataDaoManager.queryAllDataByAddress();
        for (HeartData heartData : heartDataList) {
            int hr = heartData.getHeart();
            String time = heartData.getTime();
           // Log.i(TAG, "createHeartDataForRequest: "+time);
            long startTime = DateUtil.getDefaultLongMi(time);
            long endTime = startTime +  60 * 1000l;
            DataPoint dataPoint =
                    dataSetHr.createDataPoint().setTimeInterval(startTime, endTime, TimeUnit.MILLISECONDS);
            dataPoint.getValue(Field.FIELD_BPM).setFloat(hr);
            dataSetHr.add(dataPoint);
        }
        insetData(dataSetHr, context);
    }
}
